<template>
  <div class="app-container">
    <el-row :gutter="20" style="display: flex;">
      <el-col :span="8" :xs="24">
        <!-- UserCard 组件 -->
        <el-card style="height: calc(100% - 10px)">
          <template #header>
            <div class="card-header">
              <span>个人信息</span>
            </div>
          </template>

          <div class="user-profile">
            <div class="box-center">
              <el-avatar :size="100" :src="user.avatar" fit="cover"/>
            </div>
            <div class="box-center">
              <div class="user-name">{{ user.user?.name }}</div>
              <div class="user-role">{{ user.job || '未设置职位' }}</div>
            </div>
          </div>

          <div class="user-bio">
            <div class="user-bio-section">
              <div class="user-bio-section-header">
                <i class="el-icon-user"></i>
                <span>基本信息</span>
              </div>
              <div class="user-bio-section-body">
                <div class="text-item">
                  <i class="el-icon-office-building"></i>
                  <span>学院：</span>
                  <span>{{ user.school?.name || '未设置' }}</span>
                </div>
                <div class="text-item">
                  <i class="el-icon-reading"></i>
                  <span>专业：</span>
                  <span>{{ user.major?.name || '未设置' }}</span>
                </div>
                <div class="text-item">
                  <i class="el-icon-collection-tag"></i>
                  <span>方向：</span>
                  <span>{{ user.domain?.name || '未设置' }}</span>
                </div>
                <div class="text-item">
                  <i class="el-icon-phone"></i>
                  <span>电话：</span>
                  <span>{{ user.phone || '未设置' }}</span>
                </div>
                <div class="text-item">
                  <i class="el-icon-message"></i>
                  <span>邮箱：</span>
                  <span>{{ user.user?.email || '未设置' }}</span>
                </div>
                <div class="text-item" v-if="user.homePage">
                  <i class="el-icon-link"></i>
                  <span>主页：</span>
                  <a :href="user.homePage" target="_blank" class="homepage-link">{{ formatHomePage(user.homePage) }}</a>
                </div>
              </div>
            </div>

            <div class="user-bio-section">
              <div class="user-bio-section-header">
                <i class="el-icon-document"></i>
                <span>个人简介</span>
              </div>
              <div class="user-bio-section-body">
                <div class="text-muted">
                  {{ user.description || "暂无个人简介" }}
                </div>
              </div>
            </div>
          </div>
        </el-card>
      </el-col>

      <el-col :span="16" :xs="24">
        <el-card>
          <el-tabs v-model="activeTab">
            <!-- Account 组件 -->
            <el-tab-pane label="基本信息" name="basic">
              <el-form :model="userForm" :rules="accountRules" ref="userFormRef" label-width="100px">
                <el-form-item label="姓名" prop="name">
                  <el-input v-model="userForm.name" placeholder="请输入姓名"/>
                </el-form-item>

                <el-form-item label="电话" prop="phone">
                  <el-input v-model="userForm.phone" placeholder="请输入电话号码"/>
                </el-form-item>
                <el-form-item label="邮箱 :" prop="email">
                  <el-input v-model="userForm.email" placeholder="请输入邮箱" clearable></el-input>
                </el-form-item>
                <el-form-item label="工作情况" prop="job">
                  <el-input v-model="userForm.job" placeholder="请输入工作情况"/>
                </el-form-item>
                <el-form-item label="学院专业 :" prop="schoolMajor">
                  <el-cascader v-model="userForm.schoolMajor" :options="schoolMajorData"/>
                </el-form-item>
                <el-form-item label="研究方向 :" prop="domain">
                  <el-cascader v-model="userForm.domain" :options="DomainOptions"/>
                </el-form-item>
                <el-form-item label="个人主页" prop="homePage">
                  <el-input v-model="userForm.homePage" placeholder="请输入个人主页地址"/>
                </el-form-item>

                <el-form-item label="个人简介" prop="description">
                  <el-input type="textarea" v-model="userForm.description" :rows="4" placeholder="请输入个人简介"/>
                </el-form-item>

                <el-form-item label="头像">
                  <div class="avatar-container">
                    <cropper-image-upload :imgUrl="userForm.avatar" @uploadImgSuccess="handleAvatarChange"/>
                  </div>
                </el-form-item>

                <el-form-item>
                  <el-button type="primary" @click="submitAccountForm">保存修改</el-button>
                  <el-button @click="resetAccountForm">重置</el-button>
                </el-form-item>
              </el-form>
            </el-tab-pane>

            <!-- ChangePassword 组件 -->
            <el-tab-pane label="修改密码" name="password">
              <el-form :model="passwordForm" :rules="passwordRules" ref="passwordFormRef" label-width="100px">
                <el-form-item label="原密码" prop="oldPassword">
                  <el-input v-model="passwordForm.oldPassword" type="password" placeholder="请输入原密码"
                            show-password/>
                </el-form-item>

                <el-form-item label="新密码" prop="newPassword">
                  <el-input v-model="passwordForm.newPassword" type="password" placeholder="请输入新密码"
                            show-password/>
                </el-form-item>

                <el-form-item label="确认密码" prop="confirmPassword">
                  <el-input v-model="passwordForm.confirmPassword" type="password" placeholder="请确认新密码"
                            show-password/>
                </el-form-item>

                <el-form-item>
                  <el-button type="primary" @click="submitPasswordForm">保存修改</el-button>
                  <el-button @click="resetPasswordForm">重置</el-button>
                </el-form-item>
              </el-form>
            </el-tab-pane>
          </el-tabs>
        </el-card>
      </el-col>
    </el-row>
  </div>
</template>

<script setup lang="ts">
import {onMounted, reactive, ref} from 'vue'
import {ElMessage} from 'element-plus'
import Request from "/@/utils/Axios"
import qiniu from "/@/utils/qiniu.js"
import CropperImageUpload from "/@/components/cropperUtil/component/cropper-image-upload.vue"
import md5 from 'js-md5'
import Cookies from "js-cookie";
import {updateUser} from "/@/views/user/users";
// 定义子组件向父组件传值/事件
const emit = defineEmits(["refresh"]);
// 用户数据
const user = ref({})
const activeTab = ref('basic')

// Account 组件数据
const userFormRef = ref(null)
const userForm = reactive({
  id: '',
  name: '',
  email: '',
  phone: '',
  job: '',
  homePage: '',
  description: '',
  avatar: '',
  schoolMajor: [],
  domain: [],
})

const DomainOptions = ref([])
const accountRules = {
  name: [
    {required: true, message: '请输入姓名', trigger: 'blur'}
  ],
  phone: [
    {pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号码', trigger: 'blur'}
  ],
  homePage: [
    {
      pattern: /^(https?:\/\/)?(([\da-z.-]+)\.([a-z.]{2,6})|\/|\?|#|&|=|\w)+$/,
      message: '请输入正确的网址',
      trigger: 'blur'
    }
  ]
}
const imageFile = ref(null)

// ProfessionalInfo 组件数据
const professionalForm = reactive({
  schoolId: null,
  majorId: null,
  domainId: null
})
const majors = ref([])
const schoolMajorData = ref([])

// ChangePassword 组件数据
const passwordFormRef = ref(null)
const passwordForm = reactive({
  oldPassword: '',
  newPassword: '',
  confirmPassword: ''
})

// ChangePassword 组件方法
const validateConfirmPassword = (rule, value, callback) => {
  if (value !== passwordForm.newPassword) {
    callback(new Error('两次输入的密码不一致'))
  } else {
    callback()
  }
}
const passwordRules = {
  oldPassword: [
    {required: true, message: '请输入原密码', trigger: 'blur'}
  ],
  newPassword: [
    {required: true, message: '请输入新密码', trigger: 'blur'},
    {pattern: /(?=.*\d)(?=.*[a-zA-Z])^.{6,20}$/, message: '密码需要在6-20位之间并包含字母和数字', trigger: 'blur'}
  ],
  confirmPassword: [
    { required: true, message: '请确认新密码', trigger: 'blur' },
    { validator: validateConfirmPassword, trigger: 'blur' }
  ]
}

// 公共方法
const getUser = async () => {
  const res = await Request.get("/backapi/profile")
  user.value = res.user
  initAccountForm()
  initProfessionalForm()
}

const formatHomePage = (url) => {
  if (!url) return ''
  return url.replace(/^https?:\/\//, '').replace(/\/$/, '')
}

// Account 组件方法
const initAccountForm = () => {
  userForm.id = user.value.id
  userForm.name = user.value.user?.name || ''
  userForm.phone = user.value.phone || ''
  userForm.email = user.value.user.email || ''
  userForm.job = user.value.job || ''
  userForm.homePage = user.value.homePage || ''
  userForm.description = user.value.description || ''
  userForm.avatar = user.value.avatar || ''
  userForm.schoolMajor = [user.value.schoolId, user.value.majorId]
  userForm.domain = [user.value.domainId]
}

const handleAvatarChange = (data) => {
  userForm.avatar = data || "http://img.pzhuweb.cn/avatar";
}
const dataURLtoBlob = (dataurl) => {
  const arr = dataurl.split(","),
      mime = arr[0].match(/:(.*?);/)[1],
      bstr = atob(arr[1]);
  let n = bstr.length;
  const u8arr = new Uint8Array(n);
  while (n--) {
    u8arr[n] = bstr.charCodeAt(n);
  }
  return new Blob([u8arr], {type: mime});
};

const submitAccountForm = async () => {
  userFormRef.value.validate((valid) => {
    if (valid) {
      // 判断图片资源是本地的,还是第三方资源链接
      const strRegex = /^([hH][tT]{2}[pP]:\/\/|[hH][tT]{2}[pP][sS]:\/\/|www\.)/;
      const re = new RegExp(strRegex);
      if (!re.test(userForm.avatar)) {
        const dataBlob = dataURLtoBlob(userForm.avatar);
        const files = new File([dataBlob], Cookies.get("yourStuNum") + "tx", {
          type: dataBlob.type
        });
        qiniu(dataBlob)
            .then((res) => {
              userForm.avatar = res.key;
              updateUser({
                id: userForm.id,
                name: userForm.name,
                email: userForm.email,
                phone: userForm.phone,
                job: userForm.job,
                homePage: userForm.homePage,
                schoolMajor: userForm.schoolMajor,
                domain: userForm.domain[0],
                description: userForm.description,
                avatar: userForm.avatar,
                isCDN: 1
              })
                  .then((res) => {
                    if (res.success) {
                      setTimeout(() => {
                        emit("refresh");
                      }, 500);
                    }
                  });
            })
            .catch((err) => {
              ElMessage({
                message: "头像保存失败 !!!",
                type: "error"
              });
            });
      } else {
        updateUser({
          id: userForm.id,
          name: userForm.name,
          email: userForm.email,
          phone: userForm.phone,
          job: userForm.job,
          homePage: userForm.homePage,
          schoolMajor: userForm.schoolMajor,
          domain: userForm.domain[0],
          description: userForm.description,
          avatar: userForm.avatar,
          isCDN: 0
        })
            .then((res) => {
              if (res.success) {
                setTimeout(() => {
                  getUser()
                }, 500);
              }
            });
      }
    }
  })

}

const resetAccountForm = () => {
  userFormRef.value?.resetFields()
  initAccountForm()
}

// ProfessionalInfo 组件方法
const initProfessionalForm = () => {
  professionalForm.schoolId = user.value.schoolId || null
  professionalForm.majorId = user.value.majorId || null
  professionalForm.domainId = user.value.domainId || null

  if (professionalForm.schoolId) {
    loadMajorsBySchool(professionalForm.schoolId)
  }
}

const fetchInitData = async () => {
  try {
    const res = await Request.get("backapi/initUserMajor")
    if (res) {
      schoolMajorData.value = res.data.schoolmajor
      DomainOptions.value = res.data.domain
    }
  } catch (error) {
    console.error('获取初始化数据失败:', error)
    ElMessage.error('获取初始化数据失败')
  }
}

const loadMajorsBySchool = (schoolId) => {
  const school = schoolMajorData.value.find(s => s.value === schoolId)
  if (school && school.children && Array.isArray(school.children)) {
    majors.value = school.children
  } else {
    majors.value = []
  }
}

const submitPasswordForm = async () => {
  if (!passwordFormRef.value) return

  await passwordFormRef.value.validate(async (valid) => {
    if (valid) {
      try {
        const oldPasswordMd5 = md5(md5(passwordForm.oldPassword))
        const newPasswordMd5 = md5(passwordForm.newPassword)
        Request.post("/backapi/changePassword", {
          userId: user.value.user?.id,
          oldPassword: oldPasswordMd5,
          newPassword: newPasswordMd5
        }).then((res) => {
        })
      } catch (error) {
        console.error('提交表单出错:', error)
        ElMessage({
          message: '提交表单出错',
          type: 'error',
          duration: 5 * 1000
        })
      }
    }
  })
}

const resetPasswordForm = () => {
  passwordFormRef.value?.resetFields()
  passwordForm.oldPassword = ''
  passwordForm.newPassword = ''
  passwordForm.confirmPassword = ''
}

// 初始化
onMounted(async () => {
  await Promise.all([
    getUser(),
    fetchInitData()
  ])
})
</script>

<style lang="scss" scoped>
.app-container {
  padding: 20px;
  overflow: hidden;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.box-center {
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 8px 0;
}

.user-profile {
  text-align: center;
  padding-bottom: 20px;
  border-bottom: 1px solid #f0f0f0;

  .user-name {
    font-size: 20px;
    font-weight: bold;
    margin: 10px 0 5px;
  }

  .user-role {
    font-size: 14px;
    color: #909399;
  }
}

.user-bio {
  margin-top: 20px;

  .user-bio-section {
    margin-bottom: 20px;

    &:last-of-type {
      margin-bottom: 0;
    }

    .user-bio-section-header {
      border-bottom: 1px solid #ebeef5;
      padding-bottom: 10px;
      margin-bottom: 10px;
      font-weight: bold;
      font-size: 16px;
      display: flex;
      align-items: center;

      i {
        margin-right: 8px;
      }
    }

    .user-bio-section-body {
      .text-muted {
        color: #606266;
        line-height: 1.6;
      }

      .text-item {
        display: flex;
        align-items: center;
        margin-bottom: 8px;
        font-size: 14px;

        i {
          margin-right: 8px;
          color: #909399;
        }

        span:nth-child(2) {
          color: #606266;
          margin-right: 5px;
        }

        .homepage-link {
          color: #409EFF;
          text-decoration: none;

          &:hover {
            text-decoration: underline;
          }
        }
      }
    }
  }
}

.avatar-container {
  display: flex;
  align-items: center;
}

.avatar-preview {
  margin-left: 20px;
  border: 1px solid #ebeef5;
  border-radius: 6px;
  padding: 10px;
  background-color: #f7f7f7;
}

.avatar {
  width: 100px;
  height: 100px;
  display: block;
  object-fit: cover;
  border-radius: 50%;
}
</style>